package com.ty.xiaoyu.controller;

import com.ty.xiaoyu.XiaoyuApplication;
import com.ty.xiaoyu.entity.*;
import com.ty.xiaoyu.entity.Module;
import com.ty.xiaoyu.exception.*;
import com.ty.xiaoyu.util.Base64Util;
import com.ty.xiaoyu.util.FileUtil;
import com.ty.xiaoyu.util.MyTimeUtil;
import com.ty.xiaoyu.util.URLUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/common")
public class CommonController extends BaseController {

    Logger log = LoggerFactory.getLogger(XiaoyuApplication.class);

    private final String GREAT = "赞";
    private final String GREATId = "103";
    private final String COMMENTID = "102";

    /**
     * 获取帖子详情页
     * @param topicId 帖子id
     * @return 帖子详情、回帖列表
     */
    @GetMapping("/topicDetail")
    private Map<String, Object> getTopicDetail(@RequestParam("topicId") String topicId) {
        log.info(MyTimeUtil.nowTime() + "=== getTopicDetail star ===");
        Map<String, Object> modelMap = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        Topic topic = null;
        List<Reply> replyList = null;
        try {
            topic = topicService.getTopicById(topicId);
            // 获取贴子的回复数量
            topic.setReplyNum(replyService.getReplyNum(topic.getTopicId()));
            // 获取帖子图片
            List<TopicImage> topicImageList = topicService.getTopicImageList(topic.getTopicId());
            topic.setTopicImageList(topicImageList);
            if (loginUser != null) {
                // 获取是否已点赞
                Great great = greatService.getGreatByTopicIdAndUserId(topic.getTopicId(), loginUser.getUserId());
                topic.setGreat(great != null && great.getGreatState() != 0);
            }
            replyList = replyService.getReplyListByTopicId(topicId);
            for (Reply reply : replyList) {
                List<Comment> commentList = commentService.getCommentListByReplyId(reply.getReplyId());
                reply.setCommentList(commentList);
            }
        } catch (TopicOperationException e) {
            modelMap.put("code", 102);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== getTopicDetail 未找到帖子 ===" + e.getMessage());
            return modelMap;
        }

        data.put("topic", topic);
        data.put("replyList", replyList);
        modelMap.put("code", 0);
        modelMap.put("msg", "成功");
        modelMap.put("data", data);

        // 增加浏览次数
        try {
            Topic topicByIdForUpdate = topicService.getTopicByIdForUpdate(topicId);
            topicByIdForUpdate.setBrowseNum(topicByIdForUpdate.getBrowseNum() + 1);
            topicService.editBrowseNum(topicByIdForUpdate);
        } catch (TopicOperationException e) {
            modelMap.put("code", 106);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== getTopicDetail error ===" + e.getMessage());
            return modelMap;
        }

        // 未登录则不添加浏览记录
        if (loginUser == null) {
            log.info(MyTimeUtil.nowTime() + "=== getTopicDetail end ===");
            return modelMap;
        }
        // 新增浏览记录
        BrowsingHistory history = browsingHistoryService.getHistoryId(loginUser.getUserId(), topic.getModule().getModuleId(), topicId);
        if (history == null || "".equals(history.getHistoryId())) {
            history = new BrowsingHistory();
            history.setUser(new User());
            history.setModule(new Module());
            history.setTopic(new Topic());
            history.getUser().setUserId(loginUser.getUserId());
            history.getModule().setModuleId(topic.getModule().getModuleId());
            history.getTopic().setTopicId(topicId);
            try {
                browsingHistoryService.addHistory(history);
            } catch (BrowsingHistoryOperationException e) {
                modelMap.put("code", 105);
                modelMap.put("msg", e.getMessage());
                log.error(MyTimeUtil.nowTime() + "=== getTopicDetail 添加浏览记录失败 ===" + e.getMessage());
            }
        } else {
            try {
                browsingHistoryService.modifyHistory(history);
            } catch (BrowsingHistoryOperationException e) {
                modelMap.put("code", 106);
                modelMap.put("msg", e.getMessage());
                log.error(MyTimeUtil.nowTime() + "=== getTopicDetail 更新浏览记录失败 ===" + e.getMessage());
            }
        }
        log.info(MyTimeUtil.nowTime() + "=== getTopicDetail end ===");
        return modelMap;
    }

    /**
     * 根据浏览记录id删除浏览记录
     * @param historyId 浏览记录id
     * @return
     */
    @DeleteMapping("/deleteHistoryById")
    private Map<String, Object> deleteHistoryById(@RequestParam("historyId") String historyId) {
        log.info(MyTimeUtil.nowTime() + "=== deleteHistoryById star ===");
        Map<String, Object> modelMap = new HashMap<>();
        try {
            browsingHistoryService.deleteHistoryById(historyId);
        } catch (TopicOperationException e) {
            modelMap.put("code", 107);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== deleteHistoryById 删除失败 ===" + e.getMessage());
            return modelMap;
        }
        modelMap.put("code", 0);
        modelMap.put("msg", "成功");
        modelMap.put("data", null);
        log.info(MyTimeUtil.nowTime() + "=== deleteHistoryById end ===");
        return modelMap;
    }

    /**
     * 发布帖子
     * @param moduleId 帖子分类id
     * @param topicText 正文
     * @param place 发帖地点
     * @param topicImageList 帖子图片
     * @return
     */
    @PostMapping("/releaseTopic")
    private Map<String, Object> releaseTopic(@RequestParam("moduleId") String moduleId,
                                             @RequestParam("topicText") String topicText,
                                             @RequestParam(value = "place", required = false) String place,
                                             @RequestParam(value = "topicImageList", required = false)List<String> topicImageList) {
        log.info(MyTimeUtil.nowTime() + "=== releaseTopic star ===");
        Map<String, Object> modelMap = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        Topic topic = new Topic();
        topic.setUser(new User());
        topic.setModule(new Module());
        topic.setUserId(loginUser.getUserId());
        topic.setModuleId(moduleId);
        topic.setTopicText(topicText);
        topic.setPlace(place);
        if (topicImageList == null) {
            topicImageList = new ArrayList<>();
        }
        // 判断上传图片数量是否大于9张
        if (topicImageList.size() > 9) {
            modelMap.put("code", 301);
            modelMap.put("msg", "上传图片数量大于9张");
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== releaseTopic 保存图片出错 ===");
            return modelMap;
        }
        List<String> topicImagePathList = new ArrayList<>();
        log.debug("topicImageList.size: " + topicImageList.size());
        // 图片处理
        for (String image : topicImageList) {
            try {
                // 保存帖子图片
                String filePath = FileUtil.getTopicImagePath();
                String fileName = Base64Util.saveImage(image, filePath);
                // 获取图片地址（url）
                String url = URLUtil.getURL(request);
                String topicImagePath = url + "/image/topic/" + fileName;
                log.debug("topicImagePath: " + topicImagePath);
                topicImagePathList.add(topicImagePath);
            } catch (IOException e) {
                modelMap.put("code", 301);
                modelMap.put("msg", e.getMessage());
                modelMap.put("data", null);
                log.error(MyTimeUtil.nowTime() + "=== releaseTopic 保存图片出错 ===" + e.getMessage());
                return modelMap;
            }
        }
        try {
            topic = topicService.addTopic(topic, topicImagePathList);
        } catch (TopicOperationException e) {
            modelMap.put("code", 104);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== releaseTopic 保存图片出错 ===" + e.getMessage());
            return modelMap;
        }
        topic = topicService.getTopicById(topic.getTopicId());
        data.put("topic", topic);
        modelMap.put("code", 0);
        modelMap.put("msg", "成功");
        modelMap.put("data", data);
        log.info(MyTimeUtil.nowTime() + "=== releaseTopic end ===");
        return modelMap;
    }

    /**
     * 发布回帖
     * @param topicId 回复的帖子id
     * @param replyText 回复内容
     * @return
     */
    @PostMapping("/releaseReply")
    private Map<String, Object> releaseReply(@RequestParam("topicId") String topicId,
                                             @RequestParam("userId") String userId,
                                             @RequestParam("replyText") String replyText) {
        log.info(MyTimeUtil.nowTime() + "=== releaseReply star ===");
        Map<String, Object> modelMap = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        Reply reply = new Reply();
        reply.setTopicId(topicId);
        reply.setReplyText(replyText);
        reply.setUser(loginUser);
        try {
            reply = replyService.addReply(reply);
        } catch (ReplyOperationException e) {
            modelMap.put("code", 104);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== releaseReply ===" + e.getMessage());
            return modelMap;
        }
        // 回帖提醒
        addNotify(replyText, COMMENTID, loginUser.getUserId(), userId, topicId, null);
        reply = replyService.getReplyById(reply.getReplyId());
        data.put("reply", reply);
        modelMap.put("code", 0);
        modelMap.put("msg", "成功");
        modelMap.put("data", data);
        log.info(MyTimeUtil.nowTime() + "=== releaseReply end ===");
        return modelMap;
    }

    /**
     * 发布评论
     * @param replyId 回帖id
     * @param commentText 评论内容
     * @return
     */
    @PostMapping("/releaseComment")
    private Map<String, Object> releaseComment(@RequestParam("replyId") String replyId,
                                               @RequestParam("userId") String userId,
                                               @RequestParam("commentText") String commentText) {
        log.info(MyTimeUtil.nowTime() + "=== releaseComment star ===");
        Map<String, Object> modelMap = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        Comment comment = new Comment();
        comment.setReplyId(replyId);
        comment.setCommentText(commentText);
        comment.setUser(loginUser);
        try {
            comment = commentService.addComment(comment);
        } catch (CommentOperationException e) {
            modelMap.put("code", 104);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== releaseComment ===" + e.getMessage());
            return modelMap;
        }
        // 评论提醒
        addNotify(commentText, COMMENTID, loginUser.getUserId(), userId, null, replyId);
        comment = commentService.getCommentById(comment.getCommentId());
        data.put("comment", comment);
        modelMap.put("code", 0);
        modelMap.put("msg", "成功");
        modelMap.put("data", data);
        log.info(MyTimeUtil.nowTime() + "=== releaseComment end ===");
        return modelMap;
    }

    /**
     * 点赞或取消点赞
     * @param greatMap {
     *         topicId: '64246d1037cd441e97856ca2e4cbf426',
     *         greatStatus: false,
     *         operation: '',
     *         greatNum: 0
     *       }
     * @return
     */
    @PostMapping("/great")
    private Map<String, Object> great(@RequestBody() Map<String, Object> greatMap) {
        log.info(MyTimeUtil.nowTime() + "=== great star ===");
        Map<String, Object> modelMap = new HashMap<>();
        String topicId = (String) greatMap.get("topicId");
        Great great = greatService.getGreatByTopicIdAndUserId(topicId, loginUser.getUserId());
        // 是点赞吗
        Boolean flag = true;
        Topic topic = null;
        try {
            topic = topicService.getTopicByIdForUpdate(topicId);
            if (great == null) {
                great = new Great();
                great.setTopicId(topicId);
                great.setUserId(loginUser.getUserId());
                greatService.addGreat(great);
                topic.setGreatNum(topic.getGreatNum() + 1);
                topicService.editGreatNum(topic);
            } else if (great.getGreatState() == 0) {
                greatService.editGreat(great);
                topic.setGreatNum(topic.getGreatNum() + 1);
                topicService.editGreatNum(topic);
            } else {
                // 取消点赞
                greatService.cancelGreat(great);
                topic.setGreatNum(topic.getGreatNum() - 1);
                topicService.editGreatNum(topic);
                flag = false;
            }
        } catch (GreatOperationException e) {
            modelMap.put("code", 105);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== great error ===" + e.getMessage());
            return modelMap;
        } catch (TopicOperationException e) {
            modelMap.put("code", 106);
            modelMap.put("msg", e.getMessage());
            modelMap.put("data", null);
            log.error(MyTimeUtil.nowTime() + "=== great error ===" + e.getMessage());
            return modelMap;
        }
        if (flag) {
            // 发送点赞提醒
            addNotify(GREAT, GREATId, loginUser.getUserId(), topic.getUserId(), topic.getTopicId(), null);
        } else {
            // 删除点赞提醒
            Notify notify = notifyService.getNotifyByNotifyTypeAndSenderIdAndTopicId(GREATId, loginUser.getUserId(), topic.getTopicId());
            notifyService.cancelNotify(notify.getNotifyId());
        }
        modelMap.put("code", 0);
        modelMap.put("msg", "成功");
        modelMap.put("data", null);
        log.info(MyTimeUtil.nowTime() + "=== great end ===");
        return modelMap;
    }

    /**
     * 发送通知
     * @param notifyText
     * @param notifyModuleId
     * @param senderId
     * @param receiverId
     * @param topicId
     * @param replyId
     */
    private void addNotify(String notifyText, String notifyModuleId, String senderId, String receiverId,
                           String topicId, String replyId) {
        Notify notify = new Notify();
        notify.setNotifyText(notifyText);
        notify.setNotifyModuleId(notifyModuleId);
        notify.setSenderId(senderId);
        notify.setReceiverId(receiverId);
        if (topicId != null) {
            notify.setTopicId(topicId);
        } else if (replyId != null) {
            notify.setReplyId(replyId);
        }
        notifyService.addNotify(notify);
    }
}